﻿using AutoMapper;
using IdGen;
using KWT.DRG_DIP.API.Infrastructure;
using KWT.DRG_DIP.DB;
using KWT.DRG_DIP.DO.System;
using KWT.DRG_DIP.ISvc;
using KWT.DRG_DIP.PO.Basic;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;

namespace KWT.DRG_DIP.API
{
    [ApiController]
    [CommonExceptionFilter]
    [Authorize]
    public class ApiControllerBase : ControllerBase
    {
        /// <summary>
        /// 雪花ID生成器
        /// </summary>
        public IIdGenerator<long> snow_id { get; set; }
        #region Service 属性引用
        public IMapper _mapper { get; set; }
        public IHttpContextAccessor _contextAccessor { get; set; }
        public IWebHostEnvironment _env { get; set; }
        public EFContext ef { get; set; }

        public MainEFContext main { get; set; }
        public IJwtSvc jwtSvc { get; set; }
        public DapperHelper dapper { get; set; }
        #endregion

        #region 自定义动作
        protected internal virtual OutputResult Output(bool flag, string succ, string fail, object? data = null, int code = 0) => new(flag, succ, fail, data, code);
        protected internal virtual OutputResult Success(string succ) => new(true, succ);
        protected internal virtual OutputResult Fail(string fail, int code = 0) => new(false, "", fail, code);
        protected internal virtual PageListResult PageList(object list, int total) => new(list, total);
        protected internal virtual FileResult PDF(string file_name, byte[] bytes) => File(bytes, "application/octet-stream", file_name + ".pdf");
        protected internal virtual FileResult Word(string file_name, byte[] bytes) => File(bytes, "application/vnd.openxmlformats-officedocument.wordprocessingml.document", file_name + ".docx");
        protected internal virtual FileResult Excel(string file_name, byte[] bytes) => File(bytes, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", file_name + ".xlsx");
        protected internal virtual FileResult PPT(string file_name, byte[] bytes) => File(bytes, "application/vnd.openxmlformats-officedocument.presentationml.presentation", file_name + ".pptx");
        #endregion

        #region 当前用户
        public Current_User CurrentUser
        {
            get
            {
                string user_id = _contextAccessor.HttpContext?.User.Claims.First().Value;
                string tenantID = _contextAccessor.HttpContext?.Request.Headers["TenantID"];
                if (!string.IsNullOrEmpty(user_id))
                {
                    if (RedisHelper.HExists("CurrentUser-" + tenantID, user_id))
                    {
                        return RedisHelper.HGet<Current_User>("CurrentUser-" + tenantID, user_id);
                    }

                    string sql = "select * from sys_user where userid=@user_id";
                    var sysUser = dapper.SelectSingle<Sys_User>(sql, new { user_id });

                    string _sql = "select * from User_AreaRoleDeptCategory where userid=@userid";
                    var ua = dapper.Select<User_AreaRoleDeptCategory>(_sql, new { userid = user_id });
                    var tenant = dapper.SelectSingle<Sys_Tenant>("select * from sys_tenant where tenantID=@TenantID", new { sysUser.TenantID });
                    var user = new Current_User()
                    {
                        UserID = user_id,
                        UsePolicy = tenant.UsePolicy,
                        LoginName = sysUser.LoginName,
                        RealName = sysUser.RealName,
                        TenantID = sysUser.TenantID,
                        AreaIDs = [.. ua.Select(x => x.AreaID)],
                        RoleIDs = [.. ua.Select(x => x.RoleID)],
                        CategoryIDs = [.. ua.Select(x => x.CategoryID)],
                        IsAuth = true,
                        RoleID = sysUser.RoleID
                    };

                    if (sysUser.RoleID == "99" || ua.Select(x => x.RoleID).Any(x => x == "5"))
                    {
                        user.IsAuth = false;
                        RedisHelper.HSet("CurrentUser-" + tenantID, user_id, user);
                        return user;
                    }
                    if (ua.Select(x => x.RoleID).Any(x => x == "3"))
                    {
                        string sql1 = "select CategoryID from Sys_Category where PID=@CategoryID";
                        var categoryIds = dapper.Select<string>(sql1, new { ua.Single(x => x.RoleID == "3").CategoryID }).ToList();
                        categoryIds.AddRange(ua.Where(x => x.RoleID != "3").Select(x => x.CategoryID));
                        user.CategoryIDs = categoryIds;
                        RedisHelper.HSet("CurrentUser-" + tenantID, user_id, user);
                        return user;
                    }
                    RedisHelper.HSet("CurrentUser-" + tenantID, user_id, user);
                    return user;
                }
                else
                {
                    throw new Exception("user_id为空");
                }
            }
            private set { }
        }
        #endregion
    }
}